package com.yanqu.road.server.gameplayer.module.specialserver;

import com.yanqu.road.dao.impl.player.UserCommonActivityDataDaoImpl;
import com.yanqu.road.entity.autodata.specialserver.IceServerNpcData;
import com.yanqu.road.entity.autodata.specialserver.IceServerUserData;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eSpecialServerType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.servercenter.ServerInfo;
import com.yanqu.road.entity.specialserver.IceServerBurnConfig;
import com.yanqu.road.entity.specialserver.IceServerStoveLevelConfig;
import com.yanqu.road.logic.config.ChannelConfig;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.pb.specialserver.IceServerProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.gameplayer.module.player.EarnSpeedModule;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.specialserver.IceServerMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 寒冬汴梁
 */
public class IceServerModule extends GeneralModule {

    private IceServerUserData userData;

    private AtomicInteger maxNpcId;

    public IceServerModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        userData = new UserCommonActivityDataDaoImpl<IceServerUserData>().getUserActivityData(IceServerUserData.class, player.getUserId());

        int tmpMaxNpcId = 0;
        if (userData != null) {
            for (IceServerNpcData npcData : userData.getNpcDataList()) {
                tmpMaxNpcId = Math.max(npcData.getNpcId(), tmpMaxNpcId);
            }
        }
        maxNpcId = new AtomicInteger(tmpMaxNpcId);
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return false;
    }

    @Override
    public boolean saveData() {
        if (userData != null) {
            if (userData.isInsertOption()) {
                new UserCommonActivityDataDaoImpl<IceServerUserData>().add(userData);
            } else if (userData.isUpdateOption()) {
                new UserCommonActivityDataDaoImpl<IceServerUserData>().update(userData);
            }
        }
        return true;
    }

    @Override
    public void loginSendMsg() {
        ServerInfo serverInfo = ServerListMgr.getServerInfo(GameServer.getInstance().getServerId());
        if (serverInfo.getSpecialServer() != eSpecialServerType.IceServer.getValue() && !SystemOpenMgr.systemOpen(player, eSystemId.IceServer.getValue())) {
            return;
        }
        // 判断区服是否开放
        boolean isOpen = false;
        if (serverInfo.getSpecialServer() == eSpecialServerType.IceServer.getValue()) {
            // 寒冬特色服默认开放
            isOpen = true;
        }
        // 看下是否满足开放配置的区服
        List<String> openServerList = StringUtils.stringToStringList(ChannelConfig.ICE_SERVER_OPEN_SERVER, "\\|");
        for (String openServerParam : openServerList) {
            List<Long> openServer = StringUtils.stringToLongList(openServerParam, "-");
            if (serverInfo.getServerId() >= openServer.get(0) && serverInfo.getServerId() <= openServer.get(1)) {
                isOpen = true;
                break;
            }
        }
        if (!isOpen) {
            return;
        }

        initSystem();
    }

    public void initSystem() {
        // 初始化用户数据
        initUserData();

        // 同步用户数据
        syncUserData();
    }

    /**
     * 初始化用户数据
     */
    private synchronized void initUserData() {
        if (userData != null) {
            return;
        }
        userData = new IceServerUserData();
        userData.setUserId(player.getUserId());
        userData.setGuideId(0);
        userData.setSatiation(0);
        // 初始温度
//        List<Integer> temperatureList = StringUtils.stringToIntegerList(GameConfig.ICE_SERVER_TEMP, ";");
//        userData.setTemperature(temperatureList.get(0));
        // 又不要初始值了， 温度改为建造数量
        userData.setTemperature(0);
        userData.setStoveExp(0);
        userData.setStoveLv(1);
        userData.setTaskStartTime(0);
        userData.setSpecialSilver(0);
        userData.setTaskCompleteTimeMap(new HashMap<>());
        userData.setInsertOption();

        // 初始化燃烧物
        initStoveItem();
        // 初始化npc
        initNpcData();
    }

    private void initNpcData() {
        while (userData.getNpcDataList().size() < IceServerMgr.MAX_NPC_NUM) {
            IceServerNpcData npcData = createNpcData();
            userData.addNpcData(npcData);
        }
    }

    private IceServerNpcData createNpcData() {
        IceServerNpcData npcData = new IceServerNpcData();
        npcData.setNpcId(maxNpcId.incrementAndGet());
        npcData.setCurValue(0);
        npcData.setMaxValue(IceServerMgr.getRandomCoalNum());
        return npcData;
    }

    private void initStoveItem() {
        if (userData == null) {
            return;
        }
        int initStoveItem = IceServerMgr.getInitStoveItem();
        userData.setUnlockStoveItem(new HashSet<>());
        userData.addUnlockStoveItem(initStoveItem);
        userData.setStoveItem(initStoveItem);
    }

    /**
     * 同步用户数据
     */
    public void syncUserData() {
        IceServerProto.IceServerUserDataSyncMsg.Builder builder = IceServerProto.IceServerUserDataSyncMsg.newBuilder();
        builder.setUserData(parseUserDataMsg(userData));
        player.sendPacket(GameProtocol.S_ICE_SERVER_SYNC_USER_DATA % 20000, builder);
    }

    public IceServerProto.IceServerUserDataMsg.Builder parseUserDataMsg(IceServerUserData userData) {
        if (userData == null) {
            return null;
        }
        IceServerProto.IceServerUserDataMsg.Builder builder = IceServerProto.IceServerUserDataMsg.newBuilder();
        builder.setGuideId(userData.getGuideId());
        builder.setSatiation(userData.getSatiation());
        builder.setTemperature(userData.getTemperature());
        builder.setStoveExp(userData.getStoveExp());
        builder.setStoveLv(userData.getStoveLv());
        builder.setStoveItem(userData.getStoveItem());
        builder.setTaskStartTime(userData.getTaskStartTime());
        builder.addAllUnlockStoveItem(userData.getUnlockStoveItem());
        for (IceServerNpcData npcData : userData.getNpcDataList()) {
            builder.addNpcData(parseIceServerNpcDataMsg(npcData));
        }
        builder.setSpecialSilver(userData.getSpecialSilver());
        builder.setTaskFinishTime(userData.getTaskFinishTime());
        for (Map.Entry<Integer, Long> entry : userData.getTaskCompleteTimeMap().entrySet()) {
            IceServerProto.IceServerTaskCompleteMsg.Builder taskCompleteMsg = IceServerProto.IceServerTaskCompleteMsg.newBuilder();
            taskCompleteMsg.setTaskId(entry.getKey());
            taskCompleteMsg.setCompleteTime(entry.getValue());
            builder.addTaskCompleteTime(taskCompleteMsg);
        }
        return builder;
    }

    public IceServerProto.IceServerNpcDataMsg.Builder parseIceServerNpcDataMsg(IceServerNpcData npcData) {
        if (npcData == null) {
            return null;
        }
        IceServerProto.IceServerNpcDataMsg.Builder builder = IceServerProto.IceServerNpcDataMsg.newBuilder();
        builder.setNpcId(npcData.getNpcId());
        builder.setCurValue(npcData.getCurValue());
        builder.setMaxValue(npcData.getMaxValue());
        return builder;
    }

    /**
     * 完成引导
     *
     * @param guideId 引导id
     */
    public int finishGuide(int guideId) {
        if (userData == null) {
            return GameErrorCode.E_ERROR_DATA;
        }
        userData.setGuideId(guideId);
        IceServerProto.IceServerFinishGuideRespMsg.Builder respMsg = IceServerProto.IceServerFinishGuideRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setGuideId(userData.getGuideId());
        player.sendPacket(Protocol.S_ICE_SERVER_FINISH_GUIDE % 20000, respMsg);

        syncUserData();
        return 0;
    }

    public IceServerUserData getUserData() {
        return userData;
    }

    /**
     * 增加饱腹度
     *
     * @param addValue 增加的值
     */
    public void addSatiation(BigInteger addValue) {
        if (userData == null) {
            return;
        }
        userData.setSatiation(userData.getSatiation() + addValue.intValue());
        player.notifyListener(eGamePlayerEventType.IceServerSatiation.getValue());

        // 同步一下
        syncUserData();
    }

    /**
     * 增加体温
     *
     * @param addValue 增加的值
     */
    public void addTemperature(BigInteger addValue) {
        if (userData == null) {
            return;
        }
        userData.setTemperature(userData.getTemperature() + addValue.intValue());
        player.notifyListener(eGamePlayerEventType.IceServerTemperature.getValue());

        // 同步一下
        syncUserData();
    }

    /**
     * 点击熔炉
     */
    public int touchStove(int times) {
        if (userData == null) {
            return GameErrorCode.E_ERROR_DATA;
        }
        // 做个频率校验
        times = Math.min(times, GameConfig.ICE_SERVER_BURN_LIMIT);

        IceServerStoveLevelConfig stoveLevelConfig = IceServerMgr.getStoveLevelConfig(userData.getStoveLv());
        if (stoveLevelConfig == null) {
            return GameErrorCode.E_ICE_SERVER_STOVE_LEVEL_ERROR;
        }
        IceServerBurnConfig burnConfig = IceServerMgr.getBurnConfig(userData.getStoveItem());
        if (burnConfig == null) {
            return GameErrorCode.E_ICE_SERVER_BURN_ITEM_ERROR;
        }
        IceServerProto.IceServerTouchStoveRespMsg.Builder respMsg = IceServerProto.IceServerTouchStoveRespMsg.newBuilder();

        // 总获得的煤炭
        int totalCoalNum = stoveLevelConfig.getCoalNum() * times;
        // 增加熔炉经验
        userData.setStoveExp(userData.getStoveExp() + stoveLevelConfig.getTouchAddExp() * times);

        long addSilver = 0;
        while (totalCoalNum > 0) {
            IceServerNpcData npcData = userData.getNpcDataList().get(0);
            // 最大能接收多少煤
            int maxReceiveNum = npcData.getMaxValue() - npcData.getCurValue();
            if (maxReceiveNum > totalCoalNum) {
                maxReceiveNum = totalCoalNum;
            }
            npcData.setCurValue(npcData.getCurValue() + maxReceiveNum);
            totalCoalNum -= maxReceiveNum;
            if (npcData.getCurValue() >= npcData.getMaxValue()) {
                // 满了之后获得银两并移除
                if (respMsg.getFinishNpcDataBuilderList().size() < 10) {
                    respMsg.addFinishNpcData(parseIceServerNpcDataMsg(npcData));
                }
                // 获得的银两
                addSilver = npcData.getMaxValue() * burnConfig.getSilver();
                userData.getNpcDataList().remove(npcData);
                // 增加个新的
                IceServerNpcData newNpcData = createNpcData();
                userData.getNpcDataList().add(newNpcData);
            }
        }
        // 银两改成数据，添加银两
        if (addSilver > 0) {
            userData.setSpecialSilver(userData.getSpecialSilver() + addSilver);
            player.notifyListener(eGamePlayerEventType.IceServerAddSliver.getValue(), addSilver);
        }

        respMsg.setRet(0);
        respMsg.setStoveExp(userData.getStoveExp());
        for (IceServerNpcData npcData : userData.getNpcDataList()) {
            respMsg.addNpcData(parseIceServerNpcDataMsg(npcData));
        }
        respMsg.setSpecialSilver(userData.getSpecialSilver());
        player.sendPacket(Protocol.S_ICE_SERVER_TOUCH_STOVE % 20000, respMsg);
        return 0;
    }

    /**
     * 升级熔炉
     *
     * @param times 升级次数
     */
    public int upgradeStove(int times) {
        if (userData == null) {
            return GameErrorCode.E_ERROR_DATA;
        }
        for (int i = 0; i < times; i++) {
            IceServerStoveLevelConfig stoveLevelConfig = IceServerMgr.getStoveLevelConfig(userData.getStoveLv());
            if (stoveLevelConfig == null) {
                if (i == 0) {
                    return GameErrorCode.E_ICE_SERVER_STOVE_LEVEL_ERROR;
                } else {
                    break;
                }
            }
            if (userData.getStoveLv() >= IceServerMgr.getMaxStoveLevel()) {
                if (i == 0) {
                    return GameErrorCode.E_ICE_SERVER_STOVE_MAX_LEVEL;
                } else {
                    break;
                }
            }
            if (userData.getStoveExp() < stoveLevelConfig.getNeedExp()) {
                if (i == 0) {
                    return GameErrorCode.E_ICE_SERVER_STOVE_NOT_ENOUGH_EXP;
                } else {
                    break;
                }
            } else {
                userData.setStoveLv(userData.getStoveLv() + 1);
            }
        }
        player.notifyListener(eGamePlayerEventType.IceServerUpgradeStove.getValue());

        IceServerProto.IceServerUpgradeStoveRespMsg.Builder respMsg = IceServerProto.IceServerUpgradeStoveRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setStoveLv(userData.getStoveLv());
        player.sendPacket(Protocol.S_ICE_SERVER_UPGRADE_STOVE % 20000, respMsg);
        return 0;
    }

    /**
     * 切换燃烧物
     *
     * @param stoveItem
     */
    public int changeStoveItem(int stoveItem) {
        if (userData == null) {
            return GameErrorCode.E_ERROR_DATA;
        }
        IceServerBurnConfig burnConfig = IceServerMgr.getBurnConfig(stoveItem);
        if (burnConfig == null) {
            return GameErrorCode.E_ICE_SERVER_BURN_ITEM_ERROR;
        }
        if (!userData.getUnlockStoveItem().contains(stoveItem)) {
            return GameErrorCode.E_ICE_SERVER_BURN_ITEM_NOT_UNLOCK;
        }
        userData.setStoveItem(stoveItem);
        IceServerProto.IceServerChangeStoveItemRespMsg.Builder respMsg = IceServerProto.IceServerChangeStoveItemRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setStoveItem(userData.getStoveItem());
        player.sendPacket(Protocol.S_ICE_SERVER_CHANGE_STOVE_ITEM % 20000, respMsg);
        return 0;
    }

    public int startTask(boolean isFinish) {
        if (userData == null) {
            return GameErrorCode.E_ERROR_DATA;
        }

        if (isFinish) {
            if (userData.getTaskFinishTime() != 0) {
                return GameErrorCode.E_ERROR_DATA;
            }
            // 完成任务
            userData.setTaskFinishTime(System.currentTimeMillis());

            //重新计算赚速
            player.getModule(EarnSpeedModule.class).scheduleAddSilver();
        } else {
            userData.setTaskStartTime(System.currentTimeMillis());
        }
        IceServerProto.IceServerStartTaskRespMsg.Builder respMsg = IceServerProto.IceServerStartTaskRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setTaskStartTime(userData.getTaskStartTime());
        respMsg.setTaskFinishTime(userData.getTaskFinishTime());
        player.sendPacket(Protocol.S_ICE_SERVER_START_TASK % 20000, respMsg);
        return 0;
    }

    /**
     * 解锁燃烧物
     *
     * @param stoveItem 燃烧物
     */
    public int unlockStoveItem(int stoveItem) {
        if (userData == null) {
            return GameErrorCode.E_ERROR_DATA;
        }
        IceServerBurnConfig burnConfig = IceServerMgr.getBurnConfig(stoveItem);
        if (burnConfig == null) {
            return GameErrorCode.E_ICE_SERVER_BURN_ITEM_ERROR;
        }
        if (userData.getUnlockStoveItem().contains(stoveItem)) {
            return GameErrorCode.E_ICE_SERVER_BURN_ITEM_ALREADY_UNLOCK;
        }
        if (userData.getTemperature() < burnConfig.getNeedExp()) {
            return GameErrorCode.E_ICE_SERVER_BURN_ITEM_NOT_ENOUGH_EXP;
        }
        userData.addUnlockStoveItem(stoveItem);

        player.notifyListener(eGamePlayerEventType.IceServerUnlockStoveItem.getValue());

        IceServerProto.IceServerUnlockStoveItemRespMsg.Builder respMsg = IceServerProto.IceServerUnlockStoveItemRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.addAllUnlockStoveItem(userData.getUnlockStoveItem());
        player.sendPacket(Protocol.S_ICE_SERVER_UNLOCK_STOVE_ITEM % 20000, respMsg);
        return 0;
    }

    /**
     * 建筑
     * @param silverNum 银两数量
     */
    public int unlockBuild(long silverNum) {
        if (userData == null) {
            return GameErrorCode.E_ERROR_DATA;
        }
        // 扣道具
        if (userData.getSpecialSilver() < silverNum) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }
        userData.setSpecialSilver(userData.getSpecialSilver() - silverNum);
        // 寒冬汴梁银两任务触发
        player.notifyListener(eGamePlayerEventType.IceServerAddSatiation.getValue(), silverNum);
        player.notifyListener(eGamePlayerEventType.IceServerAddTemperature.getValue(), silverNum);

        IceServerProto.IceServerUnlockBuildRespMsg.Builder respMsg = IceServerProto.IceServerUnlockBuildRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setSpecialSilver(userData.getSpecialSilver());
        player.sendPacket(Protocol.S_ICE_SERVER_UNLOCK_BUILD % 20000, respMsg);
        return 0;
    }
}
